﻿using Microsoft.AspNetCore.NodeServices;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace Core.Framework
{
    /// <summary>
    /// 限定运行权限{读写文件服务等,,,}
    /// </summary>
    public class NodeJS
    {
        public static async Task<MethodResult<T>> InvokeAsync<T>(string moduleName, params object[] args)
        {
            var result = new MethodResult<T>();

            try
            {
                var nodeServices = ProviderOfServices.GetService<INodeServices>();
                var data = await nodeServices.InvokeAsync<T>(moduleName, args).ConfigureAwait(false);
                result.IsFinished = true;
                result.Data = data;
            }
            catch (Exception ex)
            {
                result.IsFinished = false;
                result.Discription = ex.Message;
            }

            return result;

            //var taskRun = Task.Run(() =>
            //{
            //    try
            //    {
            //        var nodeServices = ProviderOfServices.GetService<INodeServices>();
            //        var task = nodeServices.InvokeAsync<T>(moduleName, args);
            //        task.ConfigureAwait(false);
            //        result.IsFinished = true;
            //        result.Data = task.Result;
            //    }
            //    catch (Exception ex)
            //    {
            //        result.IsFinished = false;
            //        result.Discription = ex.Message;
            //    }
            //});

            //taskRun.ConfigureAwait(false);
            //taskRun.Wait();

            //return Task.FromResult(result);
        }

        public static async Task<MethodResult<T>> InvokeAsync<T>(CancellationToken cancellationToken, string moduleName, params object[] args)
        {
            var result = new MethodResult<T>();

            try
            {
                var nodeServices = ProviderOfServices.GetService<INodeServices>();
                var data = await nodeServices.InvokeAsync<T>(cancellationToken, moduleName, args).ConfigureAwait(false);
                result.IsFinished = true;
                result.Data = data;
            }
            catch (Exception ex)
            {
                result.IsFinished = false;
                result.Discription = ex.Message;
            }

            return result;

            //var taskRun = Task.Run(() =>
            //{
            //    try
            //    {
            //        var task = ProviderOfServices.GetService<INodeServices>().InvokeAsync<T>(cancellationToken, moduleName, args);
            //        task.ConfigureAwait(false);
            //        result.IsFinished = true;
            //        result.Data = task.Result;
            //    }
            //    catch (Exception ex)
            //    {
            //        result.Discription = ex.Message;
            //    }
            //});

            //taskRun.ConfigureAwait(false);
            //taskRun.Wait();
            //return Task.FromResult(result);
        }

        public static async Task<MethodResult<T>> InvokeExportAsync<T>(string moduleName, string exportedFunctionName, params object[] args)
        {
            var result = new MethodResult<T>();

            try
            {
                var nodeServices = ProviderOfServices.GetService<INodeServices>();
                var data = await nodeServices.InvokeExportAsync<T>(moduleName, exportedFunctionName, args).ConfigureAwait(false);
                result.IsFinished = true;
                result.Data = data;
            }
            catch (Exception ex)
            {
                result.IsFinished = false;
                result.Discription = ex.Message;
            }

            return result;

            //var taskRun = Task.Run(() =>
            //{
            //    try
            //    {
            //        var task = ProviderOfServices.GetService<INodeServices>().InvokeExportAsync<T>(moduleName, exportedFunctionName, args);
            //        task.ConfigureAwait(false);
            //        result.IsFinished = true;
            //        result.Data = task.Result;
            //    }
            //    catch (Exception ex)
            //    {
            //        result.Discription = ex.Message;
            //    }
            //});

            //taskRun.ConfigureAwait(false);
            //taskRun.Wait();
            //return Task.FromResult(result);
        }

        public static async Task<MethodResult<T>> InvokeExportAsync<T>(CancellationToken cancellationToken, string moduleName, string exportedFunctionName, params object[] args)
        {
            var result = new MethodResult<T>();

            try
            {
                var nodeServices = ProviderOfServices.GetService<INodeServices>();
                var data = await nodeServices.InvokeExportAsync<T>(cancellationToken, moduleName, exportedFunctionName, args).ConfigureAwait(false);
                result.IsFinished = true;
                result.Data = data;
            }
            catch (Exception ex)
            {
                result.IsFinished = false;
                result.Discription = ex.Message;
            }

            return result;

            //var taskRun = Task.Run(() =>
            //{
            //    try
            //    {
            //        var task = ProviderOfServices.GetService<INodeServices>().InvokeExportAsync<T>(cancellationToken, moduleName, exportedFunctionName, args);
            //    task.ConfigureAwait(false);
            //        result.IsFinished = true;
            //        result.Data = task.Result;
            //    }
            //    catch (Exception ex)
            //    {
            //        result.Discription = ex.Message;
            //    }
            //});

            //taskRun.Wait();
        }
    }



    public class CustomLogger : ILogger
    {
        private string Provider { get; set; }

        public CustomLogger(string Provider)
        {
            this.Provider = Provider.ToLower();
        }

        public IDisposable BeginScope<TState>(TState state)
        {
            return default;
        }

        public bool IsEnabled(LogLevel logLevel)
        {
            return true;
        }

        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
        {

            //LogEntry<TState> Info = new LogEntry<TState>();
            //Info.Level = logLevel;
            //Info.Text = exception?.Message ?? state.ToString();
            //Info.Exception = exception;
            //Info.EventId = eventId;
            //Info.State = state;
            //if (state is string)
            //{
            //    Info.StateText = state.ToString();
            //}
            //else if (state is IEnumerable<KeyValuePair<string, object>> Properties)
            //{
            //    Info.StateProperties = new Dictionary<string, object>();

            //    foreach (KeyValuePair<string, object> item in Properties)
            //    {
            //        Info.StateProperties[item.Key] = item.Value;
            //    }
            //}

            //var message = formatter(state, exception);

            //File.AppendAllText(
            //    $"log_{Provider}_{logLevel.ToString()}.txt",
            //    $"\n{DateTime.Now} " + message +
            //    $"\n{Newtonsoft.Json.JsonConvert.SerializeObject(Info)} \n");
        }
    }

    public class LogEntry<TState>
    {
        public LogLevel Level { get; set; }
        public string Text { get; set; }
        public string StateText { get; set; }
        public Exception Exception { get; set; }
        public EventId EventId { get; set; }
        public TState State { get; set; }
        public Dictionary<string, object> StateProperties { get; set; }
    }

}
